home *** CD-ROM | disk | FTP | other *** search
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/wb.h>
- #include <proto/icon.h>
- #include <proto/intuition.h>
-
- #include <exec/devices.h>
- #include <devices/timer.h>
- #include <workbench/startup.h>
- #include <intuition/intuition.h>
-
- #include <dos/dos.h>
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
-
- #include "evtypes.h"
-
- void error(char *s)
- {
- struct EasyStruct es;
-
- es.es_StructSize = sizeof(es);
- es.es_Flags = 0;
- es.es_Title = "WB Clock";
- es.es_TextFormat = s;
- es.es_GadgetFormat = "Ok";
-
- EasyRequest(0, &es, 0, 0);
- }
-
- struct DiskObject *wb_disk_object(struct WBStartup *wbs)
- {
- struct WBArg *wba;
- BPTR olddir;
- struct DiskObject *dobj;
-
- wba = wbs->sm_ArgList;
- olddir = CurrentDir(wba[0].wa_Lock);
- dobj = GetDiskObject(wba[0].wa_Name);
- CurrentDir(olddir);
-
- return dobj;
- }
-
- void wb_put_disk_object(struct WBStartup *wbs, struct DiskObject *dobj)
- {
- struct WBArg *wba;
- BPTR olddir;
-
- wba = wbs->sm_ArgList;
- olddir = CurrentDir(wba[0].wa_Lock);
- PutDiskObject(wba[0].wa_Name, dobj);
- CurrentDir(olddir);
-
- return;
- }
-
- typedef struct {
- unsigned short *d;
- unsigned short width, height, ww;
- } drawsurface;
-
- void draw_line(drawsurface *ds, int x1, int y1, int x2, int y2)
- {
- int tmp, x, y, ww;
- unsigned short *d;
-
- ww = ds->ww;
-
- if (x2 < x1) {
- tmp = x1;
- x1 = x2;
- x2 = tmp;
-
- tmp = y1;
- y1 = y2;
- y2 = tmp;
- }
-
- if (y1 == y2) {
- d = &ds->d[ww * y1];
- for (; x1 <= x2; x1++) {
- d[x1 >> 4] |= 1 << (15 - (x1 & 15));
- }
- return;
- }
-
- if (x1 == x2) {
- if (y2 < y1) {
- for (; y2 <= y1; y2++) {
- d = &ds->d[ww * y2];
- d[x1 >> 4] |= 1 << (15 - (x1 & 15));
- }
- } else {
- for (; y1 <= y2; y1++) {
- d = &ds->d[ww * y1];
- d[x1 >> 4] |= 1 << (15 - (x1 & 15));
- }
- }
- return;
- }
-
- if (y2 < y1) {
- if (y1 - y2 < x2 - x1) {
- for (x = x1; x <= x2; x++) {
- tmp = ((x - x1) * (y2 - y1) + (x2 - x1)/2) / (x2 - x1) + y1;
- d = &ds->d[ww * tmp];
- d[x >> 4] |= 1 << (15 - (x & 15));
- }
- } else {
- for (y = y1; y >= y2; y--) {
- tmp = ((y - y1) * (x2 - x1) + (y2 - y1)/2) / (y2 - y1) + x1;
- d = &ds->d[ww * y];
- d[tmp >> 4] |= 1 << (15 - (tmp & 15));
- }
- }
- } else {
- if (y2 - y1 < x2 - x1) {
- for (x = x1; x <= x2; x++) {
- tmp = ((x - x1) * (y2 - y1) + (x2 - x1)/2) / (x2 - x1) + y1;
- d = &ds->d[ww * tmp];
- d[x >> 4] |= 1 << (15 - (x & 15));
- }
- } else {
- for (y = y1; y <= y2; y++) {
- tmp = ((y - y1) * (x2 - x1) + (y2 - y1)/2) / (y2 - y1) + x1;
- d = &ds->d[ww * y];
- d[tmp >> 4] |= 1 << (15 - (tmp & 15));
- }
- }
- }
- }
-
- void undraw_line(drawsurface *ds, int x1, int y1, int x2, int y2)
- {
- int tmp, x, y, ww;
- unsigned short *d;
-
- ww = ds->ww;
-
- if (x2 < x1) {
- tmp = x1;
- x1 = x2;
- x2 = tmp;
-
- tmp = y1;
- y1 = y2;
- y2 = tmp;
- }
-
- if (y1 == y2) {
- d = &ds->d[ww * y1];
- for (; x1 <= x2; x1++) {
- d[x1 >> 4] &=~ (1 << (15 - (x1 & 15)));
- }
- return;
- }
-
- if (x1 == x2) {
- if (y2 < y1) {
- for (; y2 <= y1; y2++) {
- d = &ds->d[ww * y2];
- d[x1 >> 4] &=~ (1 << (15 - (x1 & 15)));
- }
- } else {
- for (; y1 <= y2; y1++) {
- d = &ds->d[ww * y1];
- d[x1 >> 4] &=~ (1 << (15 - (x1 & 15)));
- }
- }
- return;
- }
-
- if (y2 < y1) {
- if (y1 - y2 < x2 - x1) {
- for (x = x1; x <= x2; x++) {
- tmp = ((x - x1) * (y2 - y1) + (x2 - x1)/2) / (x2 - x1) + y1;
- d = &ds->d[ww * tmp];
- d[x >> 4] &=~ (1 << (15 - (x & 15)));
- }
- } else {
- for (y = y1; y >= y2; y--) {
- tmp = ((y - y1) * (x2 - x1) + (y2 - y1)/2) / (y2 - y1) + x1;
- d = &ds->d[ww * y];
- d[tmp >> 4] &=~ (1 << (15 - (tmp & 15)));
- }
- }
- } else {
- if (y2 - y1 < x2 - x1) {
- for (x = x1; x <= x2; x++) {
- tmp = ((x - x1) * (y2 - y1) + (x2 - x1)/2) / (x2 - x1) + y1;
- d = &ds->d[ww * tmp];
- d[x >> 4] &=~ (1 << (15 - (x & 15)));
- }
- } else {
- for (y = y1; y <= y2; y++) {
- tmp = ((y - y1) * (x2 - x1) + (y1 - y2)/2) / (y1 - y2) + x1;
- d = &ds->d[ww * y];
- d[tmp >> 4] &=~ (1 << (15 - (tmp & 15)));
- }
- }
- }
- }
-
- void clear_circle(drawsurface *ds, int x, int y, int r)
- {
- int i, dx;
-
- for (i = y - r; i <= y + r; i++) {
- dx = (int)sqrt((float)(r * r - (i - y) * (i - y)));
-
- undraw_line(ds, x - dx, i, x + dx, i);
- }
- }
-
- void draw_radius(drawsurface *d1, drawsurface *d2, int x, int y, int r, double theta)
- {
- int x2, y2, dx, dy;
- double rcos, rsin;
-
- rcos = r * cos(theta);
- rsin = r * sin(theta);
-
- x2 = (int)rcos + x;
- y2 = -(int)rsin + y;
-
- if (abs(rsin) > abs(rcos)) {
- dx = 1;
- dy = 0;
- } else {
- dx = 0;
- dy = 1;
- }
-
- draw_line(d1, x + dx, y + dy, x2 + dx, y2 + dy);
- undraw_line(d2, x + dx, y + dy, x2 + dx, y2 + dy);
-
- draw_line(d2, x, y, x2, y2);
- undraw_line(d1, x, y, x2, y2);
- }
-
- void clear_clock(struct DiskObject *dobj)
- {
- struct Gadget *g;
- struct Image *i1, *i2;
- drawsurface d1a, d1b, d2a, d2b;
-
- g = &dobj->do_Gadget;
- i1 = (struct Image *)g->GadgetRender;
- i2 = (struct Image *)g->SelectRender;
-
- d1a.width = i1->Width;
- d1a.height = i1->Height;
- d1a.ww = (i1->Width + 15) / 16;
-
- d2a.width = i2->Width;
- d2a.height = i2->Height;
- d2a.ww = (i2->Width + 15) / 16;
-
- d1b = d1a;
- d2b = d2a;
-
- d1a.d = i1->ImageData;
- d2a.d = i2->ImageData;
-
- d1b.d = d1a.d + d1a.height * d1a.ww;
- d2b.d = d2a.d + d2a.height * d2a.ww;
-
- clear_circle(&d1a, d1a.width / 2, d1a.height / 2, 15);
- clear_circle(&d1b, d1b.width / 2, d1b.height / 2, 15);
-
- clear_circle(&d2a, d2a.width / 2 + 1, d2a.height / 2 + 1, 15);
- clear_circle(&d2b, d2b.width / 2 + 1, d2b.height / 2 + 1, 15);
- }
-
- void draw_time(struct timerequest *tr, struct DiskObject *dobj)
- {
- int hours, mins;
- struct Gadget *g;
- struct Image *i1, *i2;
- drawsurface d1a, d1b, d2a, d2b;
- double mtheta, htheta;
-
- mins = (tr->tr_time.tv_secs / 60) % 60;
- hours = (tr->tr_time.tv_secs / 60) % 720;
-
- g = &dobj->do_Gadget;
- i1 = (struct Image *)g->GadgetRender;
- i2 = (struct Image *)g->SelectRender;
-
- d1a.width = i1->Width;
- d1a.height = i1->Height;
- d1a.ww = (i1->Width + 15) / 16;
-
- d2a.width = i2->Width;
- d2a.height = i2->Height;
- d2a.ww = (i2->Width + 15) / 16;
-
- d1b = d1a;
- d2b = d2a;
-
- d1a.d = i1->ImageData;
- d2a.d = i2->ImageData;
-
- d1b.d = d1a.d + d1a.height * d1a.ww;
- d2b.d = d2a.d + d2a.height * d2a.ww;
-
- mtheta = PID2 - 2 * PI * mins / 60;
- htheta = PID2 - 2 * PI * hours / 720;
-
- clear_circle(&d1a, d1a.width / 2, d1a.height / 2, 15);
- clear_circle(&d1b, d1b.width / 2, d1b.height / 2, 15);
-
- clear_circle(&d2a, d2a.width / 2 + 1, d2a.height / 2 + 1, 15);
- clear_circle(&d2b, d2b.width / 2 + 1, d2b.height / 2 + 1, 15);
-
- draw_radius(&d1a, &d1b, d1b.width / 2, d1b.height / 2, 14, mtheta);
- draw_radius(&d1a, &d1b, d1b.width / 2, d1b.height / 2, 8, htheta);
-
- draw_radius(&d2a, &d2b, d1b.width / 2 + 1, d1b.height / 2 + 1, 14, mtheta);
- draw_radius(&d2a, &d2b, d1b.width / 2 + 1, d1b.height / 2 + 1, 8, htheta);
- }
-
- #define DIE_MESSAGE 0xaaff
-
- void main(int argc, char **argv)
- {
- struct DiskObject *dobj;
- struct MsgPort *timeport;
- struct timerequest *timer, *intr;
- boolean quit = false;
-
- IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0);
- if (!IntuitionBase) {
- exit(15);
- }
-
- if (timeport = FindPort("wb_clock")) {
- timer = (struct timerequest *)CreateExtIO(timeport, sizeof(*timer));
- if (!timer) {
- error("Can't create time request");
- CloseLibrary((struct Library *)IntuitionBase);
- exit(10);
- }
- timer->tr_node.io_Command = DIE_MESSAGE;
- PutMsg(timeport, (struct Message *)timer);
- CloseLibrary((struct Library *)IntuitionBase);
- exit(0);
- }
-
- IconBase = OpenLibrary("icon.library", 0);
- if (!IconBase) {
- error("Can't open icon.library");
- CloseLibrary((struct Library *)IntuitionBase);
- exit(10);
- }
-
- WorkbenchBase = OpenLibrary("workbench.library", 0);
- if (WorkbenchBase) {
- if (argc) dobj = GetDiskObject(argv[0]);
- else dobj = wb_disk_object((struct WBStartup *)argv);
-
- if (dobj) {
- timeport = CreatePort("wb_clock", 0);
- if (timeport) {
- timer = (struct timerequest *)CreateExtIO(timeport, sizeof(*timer));
- if (timer) {
- if (OpenDevice("timer.device", UNIT_VBLANK, (void *)timer, 0) == 0) {
- timer->tr_node.io_Command = TR_ADDREQUEST;
- timer->tr_time.tv_secs = 5;
- timer->tr_time.tv_micro = 0;
-
- SendIO((void *)timer);
- while (1) {
- Wait(1 << timeport->mp_SigBit);
-
- while (intr = (struct timerequest *)GetMsg(timeport)) {
- if (intr->tr_node.io_Command == DIE_MESSAGE) {
- quit = true;
- DeleteExtIO((void *)intr);
- AbortIO((void *)timer);
- continue;
- }
-
- if (quit) {
- clear_clock(dobj);
-
- if (argc) PutDiskObject(argv[0], dobj);
- else wb_put_disk_object((struct WBStartup *)argv, dobj);
-
- error("Exiting ...");
- goto quit_loop;
- }
-
- timer->tr_node.io_Command = TR_GETSYSTIME;
- DoIO((void *)timer);
-
- draw_time(timer, dobj);
-
- if (argc) PutDiskObject(argv[0], dobj);
- else wb_put_disk_object((struct WBStartup *)argv, dobj);
-
- timer->tr_node.io_Command = TR_ADDREQUEST;
- timer->tr_time.tv_secs = 60 - timer->tr_time.tv_secs % 60;
- timer->tr_time.tv_micro = 0;
- SendIO((void *)timer);
- }
- }
- quit_loop:
- CloseDevice((void *)timer);
- } else error("Can't open timer.device");
- DeleteExtIO((void *)timer);
- } else error("Can't create timer request");
- DeletePort(timeport);
- } else error("Can't create port");
- FreeDiskObject(dobj);
- } else error("Can't get disk object");
- CloseLibrary(WorkbenchBase);
- } else error("Can't open workbench.library");
-
- CloseLibrary(IconBase);
- CloseLibrary((struct Library *)IntuitionBase);
- }
-
-